package ${(projectConfig.projectPackageName)!}.common.security;

import ${(projectConfig.projectPackageName)!}.common.security.jwt.JwtUserDetails;
import ${(sbhCtx.baseDaoPackagePath)!}.UserMapper;
import ${(sbhCtx.baseEntityPackagePath)!}.User;
import cn.aezo.utils.base.MiscU;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

@Component
public class CustomUserDetailsService implements UserDetailsService {
    private final UserMapper userMapper;

    @Autowired
    public CustomUserDetailsService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(username == null || "".equals(username)) {
            throw new UsernameNotFoundException("invalid username " + username);
        }

        List<User> users = userMapper.selectByMap(MiscU.Instance.toMap("username", username));
        if(users == null || users.size() != 1) {
            throw new UsernameNotFoundException("Could not find user " + username);
        }

        User user = users.get(0);

        return new JwtUserDetails(
            user.getId(),
            user.getUsername(),
            user.getPassword(),
            AuthorityUtils.createAuthorityList("ROLE_" + user.getRoleCode())
        );

        // return new CustomUserDetails(users.get(0));
    }

    <#if "${(dependencies.weixin)!}" != "">
    public UserDetails loadUserByOpenid(String openid) throws UsernameNotFoundException {
        if(openid == null || "".equals(openid)) {
            throw new UsernameNotFoundException("invalid openid");
        }

        UserExample userExample = new UserExample();
        userExample.createCriteria().andOpenidEqualTo(openid);
        List<User> users = userMapper.selectByExample(userExample);
        if(user == null) {
            throw new UsernameNotFoundException("Could not find user by openid: " + openid);
        }

        return new JwtUserDetails(user.getId(), user.getUsername(), user.getPassword(),
        AuthorityUtils.createAuthorityList("ROLE_" + user.getRoleCode()));

        // return new CustomUserDetails(users.get(0));
    }
    </#if>

    private final static class CustomUserDetails extends User implements UserDetails {
        private CustomUserDetails(User user) {
            super();
          	<#if "${(properties.userFields)!}" != "">
            	<#list properties.userFields?if_exists as item>
            this.set${item}(user.get${item}());
            	</#list>
            </#if>
        }

        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return AuthorityUtils.createAuthorityList("ROLE_" + this.getRoleCode());
        }

        @Override
        public boolean isAccountNonExpired() {
            return true;
        }

        @Override
        public boolean isAccountNonLocked() {
            return true;
        }

        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }

        @Override
        public boolean isEnabled() {
            return true;
        }

        private static final long serialVersionUID = 5639683223516504866L;
    }
}
